Drive LEDs with the Raspberry Pi GPIO pins

This notebook will walk you through using the Raspberry Pi General Purpose Input/Output (GPIO) pins to make a LED light burn.

The GPIO pins are the 40 (numbered) pins that electronic components can be connected to.

Before actually using them, we have to agree with our Raspberry Pi how to address the pins and we do that with the setmode function.

IPython Instructions:

Place your cursor in the cell below and press Shift+Enter or click the Play button in the toolbar above to execute the code in the cell.

  • Shift + Enter: Execute the cell and jump to the next one
  • Ctrl + Enter: Execute the cell, but stay in the current one
  • Alt + Enter: Execute the cell and create a new one below the current one

As long as a [*] appears to the left os the cell, it is still running. As soon as the code ends, a number appears and any output generated by the code is printed under the cell.


In [ ]:
#load GPIO library
import RPi.GPIO as GPIO
#Set BCM (Broadcom) mode for the pin numbering
GPIO.setmode(GPIO.BCM)

BCM is the numbering that is engraved on the Raspberry Pi case we use and that you can also find back on the printed Pinout schema (BCM stands for Broadcom, the company that produces the Raspberry Pi chip).

Watch out 1: a LED is a diode, which means it is important to send current through in the correct direction. So the difference between the long and short end of the LED connectors is important.

Watch out 2: if left to their own devices, LEDs will consume more current than is good for them and will subsequently burn out. If it's a bad day, the Raspberry Pi might get damaged because of it... To prevent this, we need to add a resistor (in series!)

  1. Connect the long end of the LED with GPIO18 on the Pi.

  2. Place a low value resistor (220-360 Ohm) in series with the LED.

Illustration:

Then all that is left in our setup is to tell the Raspberry Pi that we intend to use GPIO18 as output, so we can change the voltage on that pin. This way we can send current on the pin to turn on the LED.


In [ ]:
# If we assign the name 'PIN' to the pin number we intend to use, we can reuse it later
# yet still change easily in one place
PIN = 18

# set pin as output
GPIO.setup(PIN, GPIO.OUT)

With all GPIO settings done, we can put pin GPIO18 to work.

To do this, we import the time library, so we can use its time related functionality: time.sleep(x) is a function that tells the computer to wait for a number of seconds before continuing with the next instruction.


In [ ]:
import time

# Repeat forever
while True:
    # turn off pin 18
    GPIO.output(PIN, 0)
    # wait for half a second
    time.sleep(.5)
    # turn on pin 18
    GPIO.output(PIN, 1)
    # wait for half a second
    time.sleep(.5)
    #... and again ...

Note: To stop the running code, you can:

  • click the stop button in the toolbar above
  • choose Kernel > Interrupt from the dropdown menu
  • use a keyboard shortcut: type i twice (only while the cell is in "command mode" (indicated by a grey border).

Pulse Width Modulation

So we can now send binary commands ("on" and "off"), but the GPIO library also allows us to simulate an analog signal, also called PWM (Pulse Width Modulation). A PWM signal consists of a quick succession of on and off signals where the ratio between the total on and the total off time indicates the pseudo-analog level between 0 and 1.

E.g. 75% of the time "on" == a duty cycle of 75% == an analog signal of 0.75 (or 75% of the max amplitude)

In the case of a LED, this will manifest itself as a stronger or weaker light being emitted from the LED. In different motors this can be the rotating speed or the angle to which the axis moves (or is held).


In [ ]:
#reset the GPIO
PIN = 18
GPIO.cleanup()
GPIO.setmode(GPIO.BCM)
GPIO.setup(PIN, GPIO.OUT)

In [ ]:
# Create PWM object and set its frequency in Hz (cycles per second)
led = GPIO.PWM(PIN, 60)

# Start PWM signal
led.start(0)

try:
    while True:
        # increase duty cycle by 1%
        for dc in range(0, 101, 1):
            led.ChangeDutyCycle(dc)
            time.sleep(0.05)
        # and down again ...
        for dc in range(100, -1, -1):
            led.ChangeDutyCycle(dc)
            time.sleep(0.05)
except KeyboardInterrupt:
    pass
led.stop()

In [ ]:
GPIO.cleanup()